package com.visionblue.business.ship.print

import android.content.Context
import android.hardware.usb.UsbConstants
import android.hardware.usb.UsbDeviceConnection
import android.hardware.usb.UsbEndpoint
import android.hardware.usb.UsbManager
import com.tencent.bugly.crashreport.CrashReport
import com.visionblue.business.ship.util.GBKHexUtil
import com.visionblue.business.ship.util.MLog

/**
 * @author: xlh
 * @date: 2020-06-28 3:31 PM
 * @desc:
 */
class UsbPrinter(val context: Context) : IPrinter {

    private var usbEndpointIn: UsbEndpoint? = null
    private var usbEndpointOut: UsbEndpoint? = null
    private var usbConn: UsbDeviceConnection? = null

    override fun print(byteArray: ByteArray) {
        if (usbConn == null) {
            initUsb()
            write(byteArray)
        } else {
            write(byteArray)
        }
    }

    private fun initUsb() {
        val usbManager = context.getSystemService(Context.USB_SERVICE) as UsbManager?
//        val usbDevice = usbManager?.deviceList?.get(USB4)
        //mVendorId=19267,mProductId=13624
        val usbDevices = usbManager?.deviceList
            ?.filter { it.value.vendorId == 19267 && it.value.productId == 13624 }
        usbDevices?.forEach {
            MLog.e("${it.key} =  ${it.value}")
//            CrashReport.postCatchedException(Exception("${it.key} =  ${it.value}"))
        }
        if (usbDevices != null && usbDevices.isNotEmpty()) {
            usbDevices.forEach {
                val usbDevice = it.value
                if (usbDevice != null) {
                    val usbInterface = usbDevice.getInterface(0)
                    val usbConn = usbManager.openDevice(usbDevice)
                    if (usbConn != null && usbConn.claimInterface(usbInterface, true)) {
                        this.usbConn = usbConn
                        repeat(usbInterface.endpointCount) {
                            val endpoint = usbInterface.getEndpoint(it)
                            if (endpoint.direction == UsbConstants.USB_DIR_IN) {
                                usbEndpointIn = endpoint
                            } else {
                                usbEndpointOut = endpoint
                            }
                        }
                    } else {
                        usbConn?.close()
                        this.usbConn = null
                    }
                }
            }
        } else {
            throw OpenPrinterException()
        }
    }

    private fun write(byteArray: ByteArray) {
        MLog.e(GBKHexUtil.bytes2HexString(byteArray))
        MLog.e("conn = $usbConn endpoint = $usbEndpointOut")
        if (usbConn == null) {
            throw PrinterWriteException()
        }
        usbConn?.bulkTransfer(usbEndpointOut, byteArray, byteArray.size, 1000)
    }

    companion object {
//        private const val USB4 = "/dev/bus/usb/004/003"
    }
}